Skip to content

[pull] main from MetaMask:main#352

Merged
pull[bot] merged 9 commits into
Reality2byte:mainfrom
MetaMask:main
Nov 25, 2025
Merged

[pull] main from MetaMask:main#352
pull[bot] merged 9 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Nov 25, 2025

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

salimtb and others added 9 commits November 25, 2025 08:06
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
build sites section feature for trending
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: build sites section for trending

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**


https://github.com/user-attachments/assets/d22bb8e0-d225-40fb-9280-bc4da19ca40d


<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduces a new Sites section in Explore, with a full list view,
in-app search (URL/Google shortcuts), API-backed data, navigation route,
and supporting UI/tests; includes minor Predict UI and header tweaks.
> 
> - **Explore/Trending**:
> - **New `sites` section** integrated into `SECTIONS_CONFIG`,
`HOME_SECTIONS_ARRAY`, `SECTIONS_ARRAY`, and `useSectionsData`.
> - **API hook**: `useSitesData` fetches/normalizes sites from
`portfolio.api.cx.metamask.io` with tests.
>   - **UI**:
> - `SitesListView` screen with search, URL/Google footer actions,
skeletons, and site rows.
> - `SectionSites` components: `SiteRowItem`, `SiteRowItemWrapper`
(navigates to `TrendingBrowser`), `SiteSkeleton`.
> - Adds `Routes.SITES_LIST_VIEW` and stacks it in `TrendingHome`
navigator.
> - Search bar supports custom `placeholder`; Explore search results
footer layout refined.
> - **Search**: `ExploreSearchResults` and tests updated to include
`sites` dataset/state.
> - **Styling/UX tweaks**:
> - Predict market components: adjust paddings, button sizes/variants,
carousel layout.
> - `TrendingTokensFullView` header text variant updated to `HeadingLG`.
> - **Localization**: adds `trending.sites`, `trending.popular_sites`,
`trending.search_sites` strings.
> - **Tests**: comprehensive additions for sites hook, list view, row
item, skeleton, and updated explore search tests.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
024f048. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Swaps team is in process of removing the legacy swaps module and all
related directories. While scanning the codebase, we found out that
Ramps team is consuming the `ShapesBackgroundAnimation` component. After
we delete the `app/components/UI/Swaps` directory the only reference to
`ShapesBackgroundAnimation` will be from within Ramp. For that reason,
we introduce this PR that transfers the ownership of that component to
the ramps team, placing it under their respective components directory.

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-3475

## **Manual testing steps**

```gherkin
This is a refactor that does not introduce any changes to functionality. Ensure that there are no regressions on ramps loading screen.
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Moves `ShapesBackgroundAnimation` from Swaps to Ramp Aggregator,
updates imports/usages, adds story, and adjusts tests and props.
> 
> - **Ramp UI**:
> - Move `ShapesBackgroundAnimation` to
`app/components/UI/Ramp/Aggregator/components/ShapesBackgroundAnimation`.
> - Update `Ramp/Aggregator/components/LoadingAnimation` to import the
new path.
> - Make `ShapesBackgroundAnimation` props `width`/`height` required
(remove defaults).
> - **Swaps UI**:
> - Update `Swaps/components/LoadingAnimation` to import
`ShapesBackgroundAnimation` from Ramp path.
> - **Storybook**:
> - Add story at
`Ramp/Aggregator/components/ShapesBackgroundAnimation/index.stories.tsx`
and register in `.storybook/storybook.requires.js`.
> - **Tests**:
> - Update test to import component via index (`./`) and validate
rendering with provided dimensions.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
78211e7. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…#23219)

## **Description**

Ensure MetaMask pay source transactions using gas station are supported
on chains where send bundle is supported via smart transactions.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Related to:
[#23135](#23135)

## **Manual testing steps**

## **Screenshots/Recordings**

### **Before**

### **After**

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Enables EIP-7702 gas fee tokens and routes publishing via
Delegation7702 when `isExternalSign` is set, with corresponding tests.
> 
> - **Engine: Transaction Controller**
> - `isEIP7702GasFeeTokensEnabled`: include `isExternalSign`; enable
when smart tx disabled, send bundle unsupported, or `isExternalSign` is
true.
> - `hooks.publish`: fallback to `Delegation7702PublishHook` when smart
tx disabled, send bundle unsupported, or `isExternalSign`.
> - **Tests** (`transaction-controller-init.test.ts`):
>   - Add case enabling EIP-7702 gas fee tokens when `isExternalSign`.
>   - Add case routing publish via 7702 hook when `isExternalSign`.
>   - Verify nonce lock usage via 7702 hook `getNextNonce`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
60f89c4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Refreshes multiple locale files (ko/pt/ru/tl/tr/vi) with new keys and
updated translations for perps, unified ramp, trending, mUSD conversion,
error/validation messages, and assorted copy tweaks.
> 
> - **i18n (ko, pt, ru, tl, tr, vi)**:
> - Added/updated translations and keys across multiple locale JSONs
(Korean, Portuguese, Russian, Tagalog, Turkish, Vietnamese).
> - Introduced new sections/strings: `unified_ramp`, `trending`
(Explore), mUSD conversion flow (`musd_conversion`), OHLC labels,
cross‑margin warning, funding payments, perps trade/withdrawal texts,
additional validation/error messages (e.g., `insufficient_*`,
`eligibility_failed_modal`, `price_required`, `limitPriceRequired`).
> - Standardized and refined many existing labels/placeholders,
punctuation, and wording (e.g., login placeholders, “learn more” text),
added missing translations or temporary English fallbacks.
> - Expanded UI copy for new features (Predict markets, Rewards, card
KYC/verification screens), added new navigation items (`trending`, etc.)
and improved accessibility/consistency across locales.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
25254b4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
## **Description**

This PR enhances the TradingView chart's timestamp display system to
prevent duplicate day markers and improve date label clarity across
different chart time ranges.

**What is the reason for the change?**
The TradingView chart was displaying duplicate or redundant date labels
on the X-axis, particularly when viewing charts at different time scales
(hourly, daily, weekly). This made the chart harder to read.

## **Changelog**

CHANGELOG entry: Fixed duplicate day markers on TradingView chart X-axis
and improved timestamp display clarity

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TAT-1807

## **Manual testing steps**

```gherkin
Feature: TradingView Chart Day Markers

  Scenario: user views chart with different timeframes
    Given the user is on the Perps trading screen
    And the TradingView chart is loaded with data

    When user selects different timeframes (1H, 1D, 1W)
    Then the chart should show clear day markers without duplicates
    And day boundaries should display date + time (e.g., "17 Nov 00:15")
    And subsequent hours on the same day should show time only (e.g., "01:15")
    And today's date should show time only without the date label

  Scenario: user scrolls through chart history
    Given the user has a chart with day markers displayed
    
    When user scrolls or zooms the chart to view different time periods
    Then the displayed date tracking should reset
    And new day markers should appear correctly for the newly visible range
    And no duplicate day markers should appear
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->


https://github.com/user-attachments/assets/8b2607df-38a3-4eb0-b05e-8a00a8e9fbee

### **After**

<!-- [screenshots/recordings] -->


https://github.com/user-attachments/assets/a9f5776c-0276-442c-946d-6e392c4bbd93


## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Refactors chart time label formatting to show day+month on daily ticks
and conditional date+time on intraday ticks, preventing duplicate day
markers and improving clarity across zoom ranges.
> 
> - **TradingView chart timestamp formatting**
(`app/components/UI/Perps/components/TradingViewChart/TradingViewChartTemplate.tsx`):
> - Add helpers `getDateString` and `isToday` for timezone-aware date
checks.
>   - Update `formatTimestamp`:
>     - `DayOfMonth`: always `"DD Mon"` (e.g., `17 Nov`).
> - `Hour`/`Minute`: show `"DD Mon HH:MM"` if not today, else `"HH:MM"`.
>     - `Second`: unchanged (HH:MM:SS).
> - Fallback based on visible range mirrors above rules; longer ranges
always `"DD Mon"`.
>     - Crosshair labels remain full date+time.
>   - Adjust final fallback to return `"DD Mon HH:MM"`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
418c660. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…22931)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

This PR refactors the fee and price formatting logic in the Perps
feature to improve code clarity and consistency.


## **Changelog**

CHANGELOG entry: Fixed a bug that caused too many decimals being
displayed in the order detail view

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TAT-1970

## **Manual testing steps**

```gherkin
Feature: Perps transaction fee and price display

  Scenario: user views order transaction details
    Given user has completed a perps order transaction
    When user navigates to the order transaction details view
    Then all fees and prices should display with maximum 2 decimals

  Scenario: user views position transaction details
    Given user has an open or closed perps position
    When user navigates to the position transaction details view
    Then entry price, size, and fees should display with maximum 2 decimals

```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->


https://github.com/user-attachments/assets/271fe44a-97ce-422b-ba00-f164055643e0



### **After**

<!-- [screenshots/recordings] -->
<img width="1170" height="2532" alt="Simulator Screenshot - iPhone 16e -
2025-11-19 at 13 12 40"
src="https://github.com/user-attachments/assets/7215ec22-4fcf-426b-9ea1-88c62b647bd0"
/>


## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduce formatPositiveFiat and use it for limit price, fees, entry
price, and size in Perps transaction views; update tests accordingly.
> 
> - **Utils**:
> - Replace `formatFee` with `formatPositiveFiat` in
`utils/formatUtils.ts` (same semantics: `$0`, `< $0.01`, else fiat
formatting).
> - Keep `formatPerpsFiat` as general formatter; introduce/retain
`PRICE_RANGES_UNIVERSAL`/`MINIMAL_VIEW` exports.
> - **Perps UI**:
> - `PerpsOrderTransactionView.tsx`: use `formatPositiveFiat` for
`order.limitPrice` and fee rows (`metamask_fee`, `hyperliquid_fee`,
`total_fee`).
> - `PerpsPositionTransactionView.tsx`: use `formatPositiveFiat` for
position `size`, `entry/close_price`, and `fees`; remove
`PRICE_RANGES_UNIVERSAL` usage here.
> - **Tests**:
> - Update `formatUtils.test.ts` to import and validate
`formatPositiveFiat` behavior (thresholds, rounding, stripping) and
adjust related expectations; keep comprehensive tests for
`formatPerpsFiat` and price ranges.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
bd8ed7d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…ken lists (#23107)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Implemented analytics tracking for the "View All" buttons on the Tokens
and NFTs pages to measure user engagement with the homepage performance
optimization feature.

**Reason for change:**
The recent homepage redesign added "View All" buttons to limit the
number of tokens and NFTs displayed initially. However, we weren't
tracking user interactions with these buttons, making it difficult to
understand adoption and usage patterns.

**Solution:**
- Added new Segment event `View All Assets Clicked` that fires when
users tap either button
- Event includes `asset_type` property to differentiate between Token
and NFT interactions
- Updated both TokenList and NftGrid components to track the event
- Added comprehensive unit tests to verify tracking implementation

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: TMCU-206

## **Manual testing steps**
```gherkin
Feature: View All Assets Analytics Tracking

  Scenario: user views all tokens from homepage
    Given the user is on the wallet homepage with more than 10 tokens
    When user taps the "View all tokens" button
    Then the "View All Assets Clicked" event is sent to Segment with asset_type: Token
    And user navigates to the full tokens list view

  Scenario: user views all NFTs from homepage
    Given the user is on the wallet homepage with more than 18 NFTs
    When user taps the "View all NFTs" button
    Then the "View All Assets Clicked" event is sent to Segment with asset_type: NFT
    And user navigates to the full NFTs list view
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds `VIEW_ALL_ASSETS_CLICKED` tracking with `asset_type` for Tokens
and NFTs and updates tests accordingly.
> 
> - **Analytics**
> - Add `MetaMetricsEvents.VIEW_ALL_ASSETS_CLICKED` to
`app/core/Analytics/MetaMetrics.events.ts` (enum and `events` map).
> - **UI**
> - `app/components/UI/Tokens/TokenList/index.tsx`: Track
`VIEW_ALL_ASSETS_CLICKED` with `{ asset_type: 'Token' }` in
`handleViewAllTokens`; include metrics deps in callback.
> - `app/components/UI/NftGrid/NftGrid.tsx`: Track
`VIEW_ALL_ASSETS_CLICKED` with `{ asset_type: 'NFT' }` in
`handleViewAllNfts`; include metrics deps in callback.
> - **Tests**
> - `app/components/UI/Tokens/TokenList/index.test.tsx`: Mock metrics
and assert event fired on "View all tokens" press.
> - `app/components/UI/NftGrid/NftGrid.test.tsx`: Assert event fired on
"View all NFTs" press.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d2d75cd. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

**What is the reason for the change?**

The "NFT Details Opened" Segment event was not tracking the
source/origin of where users navigate to NFT details from. This made it
impossible to differentiate between users clicking NFTs from the wallet
homepage versus the dedicated NFT list page, limiting our ability to
analyze user behavior patterns.

**What is the improvement/solution?**

Added an optional `source` parameter to the NFT Details navigation flow
and analytics tracking:
- Added `source` property to `NftDetailsParams` and
`CollectibleModalParams` types with values:
  - `'mobile-nft-list'` - when navigating from homepage NFT tab
  - `'mobile-nft-list-page'` - when navigating from full NFT list page
- Updated `NftGrid` component to pass appropriate source based on
`isFullView` prop
- Updated `NftGridItem` to propagate source parameter
- Modified analytics tracking in `NftDetails` and `CollectibleModal` to
include source in the "NFT Details Opened" event
- Added comprehensive unit tests to verify correct source values are
passed and tracked

The implementation maintains backward compatibility - the source
parameter is optional and existing navigation flows continue to work
without it.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:
[TMCU-208](https://consensyssoftware.atlassian.net/browse/TMCU-208)

## **Manual testing steps**

```gherkin
Feature: NFT Details Source Tracking

  Scenario: user navigates to NFT details from homepage

    Given user is on wallet homepage with NFTs displayed
    When user taps on an NFT in the homepage NFT tab
    Then NFT Details Opened event is tracked with source: "mobile-nft-list"

  Scenario: user navigates to NFT details from full NFT list page

    Given user has tapped "View All NFTs" from homepage
    And user is on the full NFT list page
    When user taps on an NFT
    Then NFT Details Opened event is tracked with source: "mobile-nft-list-page"
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


[TMCU-208]:
https://consensyssoftware.atlassian.net/browse/TMCU-208?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds an optional `source` param passed from NFT list views to
details/modal and includes it in the NFT details opened analytics event,
with corresponding tests.
> 
> - **Analytics**:
> - Include optional `source` in `MetaMetricsEvents.NFT_DETAILS_OPENED`
for `NftDetails` and `CollectibleModal`; effect depends on `chainId` and
`source`.
> - **Navigation/Types**:
>   - Add `source?` to `NftDetailsParams` and `CollectibleModalParams`.
> - Propagate `source` from navigation: `NftGrid` determines
(`mobile-nft-list` vs `mobile-nft-list-page`) and `NftGridItem` passes
it to `NftDetails`.
> - **UI**:
>   - `CollectibleModal` reads `source` via `useParams` and tracks it.
>   - Minor refactor in `NftGrid` to centralize content rendering.
> - **Tests**:
> - Add/extend tests in `CollectibleModal.test.tsx`, `NftGrid.test.tsx`,
and `NftDetails.test.ts` to assert `source` propagation and event
properties; update snapshots.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
169b734. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

- Small change in the `AddRewardsAccount`; this component shouldn't
deduce an account scope but always work with the one passed in as a
prop.
- Instead of using `getFirstSubscriptionId`, we are switching to
`getCandidateSubscriptionId` just like in the perps implementation & in
extension swap flow.

All flows were tested locally and still work.

## **Changelog**

CHANGELOG entry: null

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Require an explicit InternalAccount for AddRewardsAccount, update
rewards hooks to use getCandidateSubscriptionId and expose
rewardsAccountScope, and adjust UI/tests to conditionally render rewards
UI based on opt-in and scope.
> 
> - **Rewards integration**:
>   - **Hooks** (`useRewards`, `usePredictRewards`):
> - Replace `RewardsController:getFirstSubscriptionId` with
`getCandidateSubscriptionId`.
> - Return `rewardsAccountScope` and refine `shouldShowRewardsRow`
(requires opted-in or available account scope).
>   - **UI**:
> - `AddRewardsAccount`: remove account auto-derivation; now requires
explicit `account` prop and hides when absent/successful.
> - `Bridge/QuoteDetailsCard`: when rewards row is shown, display
`RewardsAnimations` if `accountOptedIn`, otherwise render
`AddRewardsAccount` with `rewardsAccountScope`; add error tooltip
handling.
> - `Predict/PredictFeeSummary`: show rewards row only if
`accountOptedIn` or `rewardsAccountScope`; pass `rewardsAccountScope` to
`AddRewardsAccount`.
> - `PredictBuyPreview`: plumbs `rewardsAccountScope` into
`PredictFeeSummary`.
> - **Tests**:
> - Update tests to mock `useRewards`, expect `rewardsAccountScope`, new
rendering conditions, and `getCandidateSubscriptionId` calls.
> - Remove Engine-based rewards mocks; add cases for
loading/error/zero-points and price impact warning flag.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2400cb8. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@pull pull Bot locked and limited conversation to collaborators Nov 25, 2025
@pull pull Bot added the ⤵️ pull label Nov 25, 2025
@pull pull Bot merged commit f53f8d6 into Reality2byte:main Nov 25, 2025
3 of 35 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants